package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.dao.local.SpecialInstructionMapper;
import com.zhijian.medical.entity.po.RoutinePatientRegist;
import com.zhijian.medical.entity.po.RoutinePatientYz;
import com.zhijian.medical.entity.po.SpecialInstruction;
import com.zhijian.medical.entity.po.SpecialInstructionMark;
import com.zhijian.medical.entity.vo.request.*;
import com.zhijian.medical.entity.vo.response.*;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.*;
import com.zhijian.util.page.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.hutool.core.collection.CollectionUtil;
import com.zhijian.util.AssertUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 特殊医嘱业务处理层
 * 
 * @author auto
 * @version: 1.0
 * @date 2024-11-06 14:14:57
 */
@Slf4j
@Service
public class SpecialInstructionServiceImpl implements SpecialInstructionService {

	@Autowired
    private SpecialInstructionMapper mapper;

    @Autowired
    private SpecialInstructionMarkService markService;

    @Autowired
    private RoutinePatientYzService yzService;
    @Autowired
    private RoutinePatientDiagnoseService diagnoseService;
    @Autowired
    private RoutineSingleSampleService singleSampleService;
    @Autowired
    private DoctorAdviceService adviceService;
    @Autowired
    private RoutinePatientRegistService registService;

    @Override
    public SpecialInstruction selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public SpecialInstructionVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Transactional(transactionManager = "localTransactionManager")
    @Override
    public void deleteById(Long id) {
        SpecialInstructionVo specialInstructionVo = mapper.selectVoById(id);
        // 删除其他模块的医嘱
        String waxBlock = specialInstructionVo.getWaxBlock();
        RoutineSingleSampleVo routineSingleSampleVo = singleSampleService.selectOne(RoutineSingleSampleSearchVo.builder()
                .number(waxBlock)
                .build());

        yzService.deleteBySampleId(routineSingleSampleVo.getId());

        List<DoctorAdviceVo> doctorAdviceVos = adviceService.selectList(DoctorAdviceSearchVo.builder().code(routineSingleSampleVo.getNumber()).status((byte) 0).build());
        for (DoctorAdviceVo doctorAdviceVo : doctorAdviceVos) {
            adviceService.deleteById(doctorAdviceVo.getId());
        }
        mapper.deleteByPrimaryKey(id);
        markService.deleteByCondition(SpecialInstructionMarkSearchVo.builder().instructionId(id).build());
    }

    @Override
    public void deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return;
        }
        mapper.deleteByIdList(idList);
    }

    @Override
    public Long insert(SpecialInstruction specialInstruction) {
        Date now = new Date();
        specialInstruction.setCreateTime(now);
        specialInstruction.setUpdateTime(now);
        return mapper.insert(specialInstruction) > 0 ? specialInstruction.getId() : 0L;
    }

    @Override
    public Long insertSelective(SpecialInstruction specialInstruction) {
        Date now = new Date();
        specialInstruction.setCreateTime(now);
        specialInstruction.setUpdateTime(now);
        return mapper.insertSelective(specialInstruction) > 0 ? specialInstruction.getId() : 0L;
    }

    @Override
    public boolean update(SpecialInstruction specialInstruction) {
        Date now = new Date();
        specialInstruction.setUpdateTime(now);
        return mapper.updateByPrimaryKey(specialInstruction) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(SpecialInstruction record) {
        Date now = new Date();
        record.setUpdateTime(now);
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Transactional(transactionManager = "localTransactionManager")
    @Override
    public boolean save(SpecialInstructionSaveOrUpdateVo saveOrUpdateVo) {
        saveOrUpdateVo.setWritePerson(CurrentUserHolder.getUser().getName());
        SpecialInstruction specialInstruction = new SpecialInstruction();
        BeanUtils.copyProperties(saveOrUpdateVo, specialInstruction);
        specialInstruction.setWritePerson(CurrentUserHolder.getUser().getName());
        Long insert = this.insertSelective(specialInstruction);
        // 保存特殊医嘱标记
        List<SpecialInstructionMarkSaveOrUpdateVo> markList = saveOrUpdateVo.getMarkList();
        String markInfoStr = "";
        if (CollUtil.isNotEmpty(markList)) {
            List<SpecialInstructionMark> entities = new ArrayList<>();
            for (SpecialInstructionMarkSaveOrUpdateVo markSaveOrUpdateVo : markList) {
                SpecialInstructionMark mark = new SpecialInstructionMark();
                BeanUtils.copyProperties(markSaveOrUpdateVo, mark);
                mark.setInstructionId(insert);
                markInfoStr += markSaveOrUpdateVo.getName() + ";";
                entities.add(mark);
            }
            markService.insertBatch(entities);
        }
        if (saveOrUpdateVo.getType().intValue() < 4) {
            // 获取蜡块号信息
            String waxBlock = saveOrUpdateVo.getWaxBlock();
            RoutineSingleSampleVo routineSingleSampleVo = singleSampleService.selectOne(RoutineSingleSampleSearchVo.builder().number(waxBlock).build());
            AssertUtil.notNull(routineSingleSampleVo, "蜡块号不存在");
            // 获取诊断信息
            RoutinePatientDiagnoseVo routinePatientDiagnoseVo = diagnoseService.selectOneById(saveOrUpdateVo.getDiagnoseId());
            RoutinePatientYz patientYz = new RoutinePatientYz();
            patientYz.setApplyDocker(saveOrUpdateVo.getPerson());
            patientYz.setPatientId(routinePatientDiagnoseVo.getPatientId());
            patientYz.setSampleId(routineSingleSampleVo.getId());
            patientYz.setYzType(Integer.valueOf(saveOrUpdateVo.getType()));
            patientYz.setRecorder(saveOrUpdateVo.getWritePerson());
            patientYz.setYzState(0);
            patientYz.setTakeNumber(markList.size() + "");
            patientYz.setNote(saveOrUpdateVo.getMark());
            patientYz.setCreateTime(DateUtil.parseDateTime(saveOrUpdateVo.getApplyTime()));
            yzService.insert(patientYz);

            if (saveOrUpdateVo.getType().intValue() == 3) {
                // 获取病人信息
                RoutinePatientRegistVo registVo = registService.selectOne(RoutinePatientRegistSearchVo.builder()
                        .patientId(routinePatientDiagnoseVo.getPatientId())
                        .build());
                // 获取诊断信息
                adviceService.save(DoctorAdviceSaveOrUpdateVo.builder()
                        .doctor(routineSingleSampleVo.getTakeDoctor())
                        .sampleType("蜡块")
                        .status((byte)0)
                        .code(routineSingleSampleVo.getNumber())
                        .name(registVo.getName())
                        .mzh(registVo.getMzh())
                        .zyh(registVo.getZyh())
                        .project(markInfoStr)
                        .sampleGatherTime(registVo.getCreateTime())
                        .issueTime(DateUtil.now())
                        .conventionPathologyNumber(registVo.getBlh())
                        .sex(registVo.getGender().equals("1") ? (byte)1 : (byte)0)
                        .age(registVo.getAge())
                        .infectedPatch(registVo.getBingQu())
                        .ch(registVo.getChuangHao())
                        .build());
            }
        }
        return insert != 0;
    }

    @Transactional(transactionManager = "localTransactionManager")
    @Override
    public boolean modify(SpecialInstructionSaveOrUpdateVo saveOrUpdateVo) {
        SpecialInstruction old = this.selectById(saveOrUpdateVo.getId());
        AssertUtil.notNull(old, "此数据不存在或者已被删除");
        SpecialInstruction specialInstruction = new SpecialInstruction();
        BeanUtils.copyProperties(saveOrUpdateVo, specialInstruction);
        // 先删除原有的标记
        markService.deleteByCondition(SpecialInstructionMarkSearchVo.builder().instructionId(saveOrUpdateVo.getId()).build());
        // 保存特殊医嘱标记
        List<SpecialInstructionMarkSaveOrUpdateVo> markList = saveOrUpdateVo.getMarkList();
        if (CollUtil.isNotEmpty(markList)) {
            List<SpecialInstructionMark> entities = new ArrayList<>();
            for (SpecialInstructionMarkSaveOrUpdateVo markSaveOrUpdateVo : markList) {
                SpecialInstructionMark mark = new SpecialInstructionMark();
                BeanUtils.copyProperties(markSaveOrUpdateVo, mark);
                mark.setInstructionId(saveOrUpdateVo.getId());
                entities.add(mark);
            }
            markService.insertBatch(entities);
        }
        return this.update(specialInstruction);
    }

    @Override
    public SpecialInstructionVo selectOne(SpecialInstructionSearchVo specialInstructionSearchVo) {
        return mapper.selectOne(specialInstructionSearchVo);
     }

    @Override
    public Integer count(SpecialInstructionSearchVo specialInstructionSearchVo) {
        return mapper.count(specialInstructionSearchVo);
    }

    @Override
    public List<SpecialInstructionVo> selectList(SpecialInstructionSearchVo specialInstructionSearchVo) {
        List<SpecialInstructionVo> specialInstructionVos = mapper.selectList(specialInstructionSearchVo);
        for (SpecialInstructionVo specialInstructionVo : specialInstructionVos) {
            List<SpecialInstructionMarkVo> specialInstructionMarkVos = markService.selectList(SpecialInstructionMarkSearchVo.builder()
                    .instructionId(specialInstructionVo.getId())
                    .build());
            int num = 0;
            for (SpecialInstructionMarkVo markVo : specialInstructionMarkVos) {
                num += markVo.getNumber();
            }
            specialInstructionVo.setMarkNum(num);
            specialInstructionVo.setMarkList(specialInstructionMarkVos);
        }
        return specialInstructionVos;
    }

    @Override
    public Page<SpecialInstructionVo> selectPage(SpecialInstructionSearchVo specialInstructionSearchVo) {
        AssertUtil.check(Objects.isNull(specialInstructionSearchVo.getPageNum()) || Objects.isNull(specialInstructionSearchVo.getPageSize()), "分页参数不能为空");
        //先直接查总数
        int count = count(specialInstructionSearchVo);
        //分页
        Page<SpecialInstructionVo> page = new Page<>(true, count, specialInstructionSearchVo.getPageNum(), specialInstructionSearchVo.getPageSize());
        specialInstructionSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<SpecialInstructionVo> responseVos = this.selectList(specialInstructionSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public boolean insertBatch(List<SpecialInstruction> entities) {
        return CollectionUtil.isNotEmpty(entities) && mapper.insertBatch(entities) > 0;
    }

    @Override
    public void deleteByCondition(SpecialInstructionSearchVo specialInstructionSearchVo) {
        //慎重用此方法！！
        mapper.deleteByCondition(specialInstructionSearchVo);
    }
    
}